package protocol;

import java.util.LinkedList;
import java.util.List;

import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

import com.netease.log.NTLog;
import com.netease.pkgRelated.ErrorToString;
import com.netease.task.TransTypeCode;
import com.netease.task.TransactionListener;

public class GroupTransactionListener implements TransactionListener {
	List<XoneCallBack> mListener;
	List<XoneCallBack> mCbListener;
	Handler mHandler = new InternalHandler();
	
//	synchronized private void beginCallBack(){
//		if(mCbListener == null){
//			mCbListener = new LinkedList<XoneCallBack>();
//		}
//		mCbListener.clear();
//		
//		if(mListener == null || mListener.size() == 0)
//			return;
//		
//		for(XoneCallBack listener : mListener)
//			mCbListener.add(listener);
//	}
//	private void endCallBack(){
//		if(mCbListener != null)
//			mCbListener.clear();
//	}
	
	@Override
	synchronized public void onTransactionError(int errCode, int type, int tid, Object err) {
		NTLog.i("GroupTransactionListener", "onTransactionError errCode = " + errCode);
		if(errCode == TransTypeCode.ERR_CODE_NO_NETWORK || errCode == TransTypeCode.ERR_CODE_NETWORK_IOEXCEPTION || errCode == TransTypeCode.ERR_CODE_NETWORK_EXCEPTION){
		    errCode = XoneServiceCode.NETWORK_ERR_COMMON;
            err = null;
		} else if (errCode < TransTypeCode.ERR_CODE_HTTP) {
		    errCode = XoneServiceCode.PROTOCOL_CODE_SEVER_ERROR;
            err = null;
        } else {
            if (errCode == XoneServiceCode.ERROR_CONTENT_NOTEXIST
                    || errCode == XoneServiceCode.ERROR_ILLEGAL_CONTENT) {
                err = null;
            }
        }
        
		String errStr = null;
		if(err != null && err instanceof String) {
			errStr = (String) err;
		}
		
		if(TextUtils.isEmpty(errStr)){
			NTLog.i("GroupTransactionListener", "onTransactionError get errStr");
			errStr = ErrorToString.getString(errCode);
		}
			
//		
//		beginCallBack();
//		for(XoneCallBack listener : mCbListener) {
//			listener.callError(arg1, arg2, errCode, errStr);
//		}
//		endCallBack();
		ResultInfo info = new ResultInfo(errCode,errStr);
		mHandler.obtainMessage(TRANSACTION_ERROR, type, tid, info)
				.sendToTarget();
	}

	@Override
	synchronized public void onTransactionMessage(int code, int type, int tid, Object obj) {
		
		if(XoneServiceCode.TRANSACTION_SUCCESS != code)
			return;
		
//		PalLog.i("TIME-TEST", "callSuccess" + System.currentTimeMillis());
//		beginCallBack();
//		for(XoneCallBack listener : mCbListener) {
//			listener.callSuccess(arg1, arg2, arg3);
//		}
//		endCallBack();
		ResultInfo info = new ResultInfo(code,obj);
		Message message = mHandler.obtainMessage(TRANSACTION_SUCCESS, type, tid, info);
		message.sendToTarget();
	}
	
	private void onSuccess(int type, int tid, int code, Object obj) {
		List<XoneCallBack> list = new LinkedList<XoneCallBack>();
		list.addAll(mListener);
		if (list.size() > 0) {
			for (XoneCallBack callback : list) {
				try {
					callback.onSuccess(type, tid, code, obj);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private void onError(int type, int tid, int errCode, Object errStr) {
		List<XoneCallBack> list = new LinkedList<XoneCallBack>();
		list.addAll(mListener);
		if (list.size() > 0) {
			for (XoneCallBack callback : list) {
				try {
					callback.onError(type, tid, errCode, (String)errStr);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 
	 * @param type
	 * @param listener
	 */
	synchronized public void addListener(XoneCallBack listener){
		if(mListener == null){
			mListener = new LinkedList<XoneCallBack>();
		}
		
		if(!mListener.contains(listener))
			mListener.add(listener);
	}
	
	synchronized public void removeListener(XoneCallBack listener){
		if(mListener != null){
    		mListener.remove(listener);
		}
	}
	
	static class ResultInfo {
		public int mcode = -1;
		public Object mObject = null;

		public ResultInfo(int code, Object object) {
			// TODO Auto-generated constructor stub
			mcode = code;
			mObject = object;
		}
	}
	
	private static final int TRANSACTION_ERROR = 0x1;
	private static final int TRANSACTION_SUCCESS = 0x2;
	
	private class InternalHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			try {
				switch (msg.what) {
				case TRANSACTION_ERROR:
					onError(msg.arg1, msg.arg2, ((ResultInfo) msg.obj).mcode,
							((ResultInfo) msg.obj).mObject);
					break;

				case TRANSACTION_SUCCESS:
					onSuccess(msg.arg1, msg.arg2, ((ResultInfo) msg.obj).mcode,
							((ResultInfo) msg.obj).mObject);
					break;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
